home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xconq / help.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  15KB  |  493 lines

  1. /* Copyright (c) 1987, 1988  Stanley T. Shebs, University of Utah. */
  2. /* This program may be used, copied, modified, and redistributed freely */
  3. /* for noncommercial purposes, so long as this notice remains intact. */
  4.  
  5. #pragma comment(exestr, "@(#) help.c 12.1 95/05/09 ")
  6.  
  7. /* RCS $Header: help.c,v 1.1 88/06/21 12:30:12 shebs Exp $ */
  8.  
  9. /* This file is devoted to commands and other functions related specifically */
  10. /* to help.  Almost all of the xconq help code is here. */
  11.  
  12. /* At least in X, the help window covers most of the xconq display, so */
  13. /* total redraws are necessary.  This can be slow - fix would be to do */
  14. /* per-window redrawing only as need, and place help window to cover as few */
  15. /* of the other windows as possible (especially world map). */
  16.  
  17. #include "config.h"
  18. #include "misc.h"
  19. #include "period.h"
  20. #include "side.h"
  21. #include "unit.h"
  22. #include "map.h"
  23.  
  24. extern int helpwinlines;
  25.  
  26. /* Display the news file on stdout if it exists, be silent if it doesn't. */
  27. /* (Used only during program startup.) */
  28.  
  29. maybe_dump_news()
  30. {
  31.     FILE *fp;
  32.  
  33.     make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
  34.     if ((fp = fopen(spbuf, "r")) != NULL) {
  35.     while (fgets(spbuf, BUFSIZE-1, fp) != NULL) {
  36.         fputs(spbuf, stdout);
  37.     }
  38.     fclose(fp);
  39.     }
  40. }
  41.  
  42. /* The general help command.  It first lists the available commands, */
  43. /* then a legend to map display, then the current news about xconq, then */
  44. /* details about the period/units.  Player can page screens back and forth, */
  45. /* which explains some odd index adjusts at bottom of loop. */
  46.  
  47. x_help(side)
  48. Side *side;
  49. {
  50.     int i = side->reqvalue2;
  51.     char opt = side->reqch;
  52.  
  53.     init_wprintf(side, NULL);
  54.     switch (opt) {
  55.     case ' ':
  56.     case 'n':
  57.     if (i < 4+period.numutypes) i++;
  58.     break;
  59.     case '-':
  60.     if (i > 0) i--;
  61.     break;
  62.     case '\014':
  63.     break;    /* redraw */
  64.     default:
  65.     conceal_help(side);
  66.     /*redraw(side);*/
  67.     return;
  68.     }
  69.     switch (i) {
  70.     case 0:
  71.     command_help(side);
  72.     break;
  73.     case 1:
  74.     legend_help(side);
  75.     break;
  76.     case 2:
  77.     make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
  78.     if (!show_file(side, spbuf)) {
  79.         wprintf(side, "No news is good news.");
  80.     }
  81.     break;
  82.     case 3:
  83.     describe_mapfiles(side);
  84.     break;
  85.     case 4:
  86.     describe_period(side);
  87.     break;
  88.     default:
  89.     /* i guaranteed to be in right range */
  90.     describe_utype(side, i - 5);
  91.     break;
  92.     }
  93.     ask_help_char(side);
  94.     request_input(side, NULL, x_help);
  95.     side->reqvalue2 = i;
  96. }
  97.  
  98. /* The command proper must request a character for whether to go to next */
  99. /* or previous screen, or to quit entirely. */
  100.  
  101. do_help(side, n)
  102. Side *side;
  103. int n;
  104. {
  105.     if (reveal_help(side)) {
  106.     init_wprintf(side, NULL);
  107.     command_help(side);
  108.     ask_help_char(side);
  109.     request_input(side, NULL, x_help);
  110.     side->reqvalue2 = 0;
  111.     }
  112. }
  113.  
  114. /* Prompt for a char from help window. */
  115.  
  116. ask_help_char(side)
  117. Side *side;
  118. {
  119.     char *help = "[Space bar to continue, '-' for prev, all else quits]";
  120.  
  121.     draw_fg_text(side, side->help, 0, (helpwinlines-1)*side->fh, help);
  122. }
  123.  
  124. /* Generate a legend for all the various symbols and pictures. */
  125. /* (Does not include cursor box or tiny side numbers.) */
  126.  
  127. legend_help(side)
  128. Side *side;
  129. {
  130.     int t, u, tcol = 2 * side->margin + side->hw;
  131.     int spacing = side->hh + 4 * side->margin;
  132.     int offset = side->hh/4, second = 30*side->fw;
  133.  
  134.     /* first column of things is constant for all periods */
  135.     draw_blast_icon(side, side->help,
  136.             side->margin, 0*spacing, 'b', side->enemycolor);
  137.     draw_fg_text(side, side->help, tcol, 0*spacing+offset, "miss");
  138.     draw_blast_icon(side, side->help,
  139.             side->margin, 1*spacing, 'c', side->enemycolor);
  140.     draw_fg_text(side, side->help, tcol, 1*spacing+offset, "hit");
  141.     draw_blast_icon(side, side->help,
  142.             side->margin, 2*spacing, 'd', side->enemycolor);
  143.     draw_fg_text(side, side->help, tcol, 2*spacing+offset, "kill");
  144.     for_all_terrain_types(t) {
  145.         char ch;
  146.         switch(side->showmode) {
  147.         case FULLHEX:
  148.         case BOTHICONS:
  149.         ch = HEX;
  150.         break;
  151.         case BORDERHEX:
  152.         ch = OHEX;
  153.         break;
  154.         case TERRICONS:
  155.         ch = ttypes[t].tchar;
  156.         break;
  157.         }
  158.     draw_hex_icon(side, side->help,
  159.               side->margin, (t+3)*spacing,
  160.               (side->monochrome ? side->fgcolor : side->hexcolor[t]),
  161.               (side->monochrome ? ttypes[t].tchar : ch));
  162.     draw_fg_text(side, side->help,
  163.              tcol, (t+3)*spacing+offset, ttypes[t].name);
  164.     }
  165.     for_all_unit_types(u) {
  166.     draw_unit_icon(side, side->help,
  167.                second, u*spacing, u, side->fgcolor);
  168.     draw_fg_text(side, side->help,
  169.              second+tcol, u*spacing+offset, utypes[u].name);
  170.     }
  171. }
  172.  
  173. /* This command provides a short note about the current hex.  It is */
  174. /* useful as a supplement to the general help command. */
  175.  
  176. do_ident(side, n)
  177. Side *side;
  178. int n;
  179. {
  180.     char view = side_view(side, side->curx, side->cury);
  181.     char t = terrain_at(side->curx, side->cury);
  182.     Side *side2;
  183.  
  184.     if (view == UNSEEN) {
  185.     notify(side, "You see unexplored territory");
  186.     } else if (view == EMPTY) {
  187.     notify(side, "You see unoccupied %s", ttypes[t].name);
  188.     } else {
  189.     side2 = side_n(vside(view));
  190.     notify(side, "You see a %s %s (in the %s)",
  191.            (side2 == NULL ? "neutral" : side2->name),
  192.            utypes[vtype(view)].name, ttypes[t].name);
  193.     }
  194. }
  195.  
  196. /* Dump out the characteristics of a single unit type.  This works by */
  197. /* jumping into the help loop, so all the other types can be looked at also. */
  198.  
  199. x_unit_info(side)
  200. Side *side;
  201. {
  202.     int u;
  203.  
  204.     if ((u = find_unit_char(side->reqch)) >= 0) {
  205.     if (u != NOTHING) {
  206.         if (reveal_help(side)) {
  207.         init_wprintf(side, NULL);
  208.         describe_utype(side, u);
  209.         ask_help_char(side);
  210.         request_input(side, NULL, x_help);
  211.         side->reqvalue2 = u;
  212.         }
  213.     }
  214.     clear_prompt(side);
  215.     } else {
  216.     request_input(side, NULL, x_unit_info);
  217.     }
  218. }
  219.  
  220. /* The command proper just prompts and issues the request. */
  221.  
  222. do_unit_info(side, n)
  223. Side *side;
  224. int n;
  225. {
  226.     ask_unit_type(side, "Details on which unit type?", NULL);
  227.     request_input(side, NULL, x_unit_info);
  228. }
  229.  
  230. /* Spit out all the general period parameters in a readable fashion. */
  231.  
  232. describe_period(side)
  233. Side *side;
  234. {
  235.     int u, r, t, i;
  236.  
  237.     wprintf(side, "This period is named \"%s\".", period.name);
  238.     wprintf(side, "");
  239.     wprintf(side,
  240.     "It includes %d unit types, %d resource types, and %d terrain types.",
  241.         period.numutypes, period.numrtypes, period.numttypes);
  242.     wprintf(side, "First unit type is %s, first product type is %s.",
  243.         (period.firstutype == NOTHING ? "none" :
  244.          utypes[period.firstutype].name),
  245.         (period.firstptype == NOTHING ? "none" :
  246.          utypes[period.firstptype].name));
  247.     wprintf(side, "");
  248.     wprintf(side,
  249.         "Countries are %d hexes across, between %d and %d hexes apart.",
  250.         period.countrysize, period.mindistance, period.maxdistance);
  251.     wprintf(side, "Known area is %d hexes across.", period.knownradius);
  252.     wprintf(side, "Default scale is %d km/hex.", period.scale);
  253.     if (period.allseen)
  254.     wprintf(side, "All units are always seen by all sides.");
  255.     wprintf(side, "");
  256.     if (period.counterattack)
  257.     wprintf(side, "Defender always gets a counter-attack.");
  258.     else
  259.     wprintf(side, "Defender does not get a counter-attack.");
  260.     wprintf(side, "Neutral units add %d%% to defense, hit over %d is a nuke.",
  261.         period.neutrality, period.nukehit);
  262.     if (period.efficiency > 0)
  263.     wprintf(side, "Unit recycling is %d%% efficient.", period.efficiency);
  264.     wprintf(side, "");
  265.     for_all_terrain_types(t) {
  266.     wprintf(side, "Terrain:  %c  %s (%s)",
  267.         ttypes[t].tchar, ttypes[t].name, ttypes[t].color);
  268.     }
  269.     wprintf(side, "");
  270.     for_all_resource_types(r) {
  271.     wprintf(side, "Resource: %c  %s (%s)",
  272.         ' ', rtypes[r].name, rtypes[r].help);
  273.     }
  274.     wprintf(side, "");
  275.     for_all_unit_types(u) {
  276.     wprintf(side, "Unit:     %c  %s (%s)",
  277.         utypes[u].uchar, utypes[u].name, utypes[u].help);
  278.     }
  279.     wprintf(side, "");
  280.     if (period.notes != NULL) {
  281.     for (i = 0; period.notes[i] != NULL; ++i) {
  282.         wprintf(side, "%s", period.notes[i]);
  283.     }
  284.     }
  285. }
  286.  
  287. /* Full details on the given type of unit.  This may be used either for */
  288. /* online help or for building a descriptive file.  The icon will only */
  289. /* show up for online help, otherwise the display calls have no effect. */
  290.  
  291. describe_utype(side, u)
  292. Side *side;
  293. int u;
  294. {
  295.     int r, t, u2;
  296.  
  297.     wprintf(side, "     '%c' %s      (territory value %d)",
  298.         utypes[u].uchar, utypes[u].name, utypes[u].territory);
  299.     wprintf(side, "            %s", utypes[u].help);
  300.     if (utypes[u].bitmapname != NULL)
  301.     wprintf(side, "     bitmap \"%s\"", utypes[u].bitmapname);
  302.     else 
  303.     wprintf(side, "");
  304.     draw_hex_icon(side, side->help, side->margin, side->margin,
  305.           side->fgcolor, HEX);
  306.     draw_unit_icon(side, side->help, side->margin, side->margin,
  307.            u, side->bgcolor);
  308.     wprintf(side, "Init: %d in country, %d/10000 hexes density, %s.",
  309.         utypes[u].incountry, utypes[u].density,
  310.         (utypes[u].named ? "named" : "unnamed"));
  311.     wprintf(side, "Maximum speed %d hexes/turn, %d%% under control. %s %s",
  312.         utypes[u].speed, utypes[u].control,
  313.         (utypes[u].onemove ? "(auto)" : ""),
  314.         (utypes[u].jumpmove ? "(jumps)" : ""));
  315.     wprintf(side, "%d HP, crippled at %d HP, chance to retreat %d%%.",
  316.         utypes[u].hp, utypes[u].crippled, utypes[u].retreat);
  317.     wprintf(side, "%d%% extra for start up, %d%% extra for R&D.",
  318.         utypes[u].startup, utypes[u].research);
  319.     wprintf(side, "%d extra moves used up by an attack.",
  320.         utypes[u].hittime);
  321.     wprintf(side,
  322.         "%d%% to succumb to siege, %d%% to revolt, attrition damage %d HP.",
  323.         utypes[u].siege, utypes[u].revolt, utypes[u].attdamage);
  324.     if (utypes[u].seerange == 1) {
  325.     wprintf(side, "Chance to see others %d%%.", utypes[u].seebest);
  326.     } else {
  327.     wprintf(side, "Chance to see %d%% at 1 hex, to %d%% at %d hexes.",
  328.         utypes[u].seebest, utypes[u].seeworst, utypes[u].seerange);
  329.     }
  330.     wprintf(side, "Own visibility is %d.", utypes[u].visibility);
  331.     if (utypes[u].volume > 0 || utypes[u].holdvolume > 0)
  332.     wprintf(side, "Volume is %d, volume of hold is %d.",
  333.         utypes[u].volume, utypes[u].holdvolume);
  334.     wprintf(side, "%s %s",
  335.         (utypes[u].changeside ? "Can be made to change sides." : ""),
  336.         (utypes[u].disband ? "Can be disbanded and sent home." : ""));
  337.     wprintf(side, "%s %s",
  338.         (utypes[u].maker ? "Builds units all the time." : ""),
  339.         (utypes[u].selfdestruct ? "Hits by self-destruction." : ""));
  340.     wprintf(side, "");
  341.     wprintf(side, "%s",
  342.         "  Resource   ToBui  Prod Store  Eats ToMov  Hits HitBy");
  343.     wprintf(side, "%s",
  344.         "               (0)   (0)   (0)   (0)   (0)   (0)   (0)");
  345.     for_all_resource_types(r) {
  346.     sprintf(spbuf, "%10s: ", rtypes[r].name);
  347.     append_number(spbuf, utypes[u].tomake[r], 0);
  348.     append_number(spbuf, utypes[u].produce[r], 0);
  349.     append_number(spbuf, utypes[u].storage[r], 0);
  350.     append_number(spbuf, utypes[u].consume[r], 0);
  351.     append_number(spbuf, utypes[u].tomove[r], 0);
  352.     append_number(spbuf, utypes[u].hitswith[r], 0);
  353.     append_number(spbuf, utypes[u].hitby[r], 0);
  354.     wprintf(side, "%s", spbuf);
  355.     }
  356.     wprintf(side, "");
  357.     wprintf(side, "%s",
  358.         "   Terrain  Slowed Rand% Hide% Defn% Prod% Attr% Acdn%");
  359.     wprintf(side, "%s",
  360.         "               (-)   (0)   (0)   (0)   (0)   (0)   (0)");
  361.     for_all_terrain_types(t) {
  362.     sprintf(spbuf, "%10s: ", ttypes[t].name);
  363.     append_number(spbuf, utypes[u].moves[t], -1);
  364.     append_number(spbuf, utypes[u].randommove[t], 0);
  365.     append_number(spbuf, utypes[u].conceal[t], 0);
  366.     append_number(spbuf, utypes[u].defense[t], 0);
  367.     append_number(spbuf, utypes[u].productivity[t], 0);
  368.     append_number(spbuf, utypes[u].attrition[t], 0);
  369.     append_number(spbuf, utypes[u].accident[t], 0);
  370.     wprintf(side, "%s", spbuf);
  371.     }
  372.     wprintf(side, "");
  373.     wprintf(side, "%s%s",
  374.         "     Hit%  Damg  Cap% Guard  Pro%",
  375.         " Holds Enter Leave  Mob% Bridg Build   Fix");
  376.     wprintf(side, "%s%s",
  377.         "      (0)   (0)   (0)   (0)   (0)",
  378.         "   (0)   (1)   (0) (100)   (0)   (0)   (0)");
  379.     for_all_unit_types(u2) {
  380.     sprintf(spbuf, "%c: ", utypes[u2].uchar);
  381.     append_number(spbuf, utypes[u].hit[u2], 0);
  382.     append_number(spbuf, utypes[u].damage[u2], 0);
  383.     append_number(spbuf, utypes[u].capture[u2], 0);
  384.     append_number(spbuf, utypes[u].guard[u2], 0);
  385.     append_number(spbuf, utypes[u].protect[u2], 0);
  386.     append_number(spbuf, utypes[u].capacity[u2], 0);
  387.     append_number(spbuf, utypes[u].entertime[u2], 1);
  388.     append_number(spbuf, utypes[u].leavetime[u2], 0);
  389.     append_number(spbuf, utypes[u].mobility[u2], 100);
  390.     append_number(spbuf, utypes[u].bridge[u2], 0);
  391.     append_number(spbuf, utypes[u].make[u2], 0);
  392.     append_number(spbuf, utypes[u].repair[u2], 0);
  393.     wprintf(side, "%s", spbuf);
  394.     }
  395.     wprintf(side, "");
  396. }
  397.  
  398. /* A simple table-printing utility. Blanks out default values so they don't */
  399. /* clutter the table. */
  400.  
  401. append_number(buf, value, dflt)
  402. char *buf;
  403. int value, dflt;
  404. {
  405.     if (value != dflt) {
  406.     sprintf(tmpbuf, "%5d ", value);
  407.     strcat(buf, tmpbuf);
  408.     } else {
  409.     strcat(buf, "      ");
  410.     }
  411. }
  412.  
  413. /* Dump assorted information into files, so they can be studied at leisure, */
  414. /* or by people with screens too small for online help. */
  415.  
  416. do_printables(side, n)
  417. Side *side;
  418. int n;
  419. {
  420.     int u;
  421.  
  422.     init_wprintf(side, CMDFILE);
  423.     command_help(side);
  424.     finish_wprintf();
  425.     notify(side, "Dumped commands to \"%s\".", CMDFILE);
  426.     init_wprintf(side, PARMSFILE);
  427.     describe_period(side);
  428.     for_all_unit_types(u) {
  429.     wprintf(side, "--------------------------------------------------");
  430.     wprintf(side, "");
  431.     describe_utype(side, u);
  432.     wprintf(side, "");
  433.     }
  434.     finish_wprintf();
  435.     notify(side, "Dumped period data to \"%s\".", PARMSFILE);
  436.     dump_view(side);
  437.     notify(side, "Dumped current view to \"%s\".", VIEWFILE);
  438. }
  439.  
  440. /* Put the current view into a file. */
  441.  
  442. dump_view(side)
  443. Side *side;
  444. {
  445.     char ch1, ch2;
  446.     int x, y, i, view, vs;
  447.     Side *side2;
  448.     FILE *fp;
  449.  
  450.     if ((fp = fopen(VIEWFILE, "w")) != NULL) {
  451.     for (y = world.height-1; y >= 0; --y) {
  452.         for (i = 0; i < y; ++i) fputc(' ', fp);
  453.         for (x = 0; x < world.width; ++x) {
  454.         view = side_view(side, x, y);
  455.         if (view == UNSEEN) {
  456.             ch1 = ch2 = ' ';
  457.         } else if (view == EMPTY) {
  458.             ch1 = ttypes[terrain_at(x, y)].tchar;
  459.             ch2 = (side->showmode == BORDERHEX ? ' ' : ch1);
  460.         } else {
  461.             ch1 = utypes[vtype(view)].uchar;
  462.             vs = vside(view);
  463.             side2 = side_n(vside(view));
  464.             ch2 = (side2 ? ((side == side2) ? ' ' : vs + '0') : '`');
  465.         }
  466.         fputc(ch1, fp);
  467.         fputc(ch2, fp);
  468.         }
  469.         fprintf(fp, "\n");
  470.     }
  471.     } else {
  472.     notify(side, "Can't open \"%s\"!!", VIEWFILE);
  473.     }
  474. }
  475.  
  476. /* This kicks in on a unit type prompt.  Just give barest details, rely */
  477. /* on general help for full unit descriptions.  This could be spiffier */
  478. /* and use the help window, but getting the interaction right is just too */
  479. /* hard... */
  480.  
  481. help_unit_type(side)
  482. Side *side;
  483. {
  484.     int u;
  485.  
  486.     for_all_unit_types(u) {
  487.     if (side->bvec[u]) {
  488.         notify(side, " %c  %s;  %s",
  489.            utypes[u].uchar, utypes[u].name, utypes[u].help);
  490.     }
  491.     }
  492. }
  493.